package com.elite.groovy.kh;

import com.elite.groovy.util.Util;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONObject;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class KHUtil {
    private static final Log log = LogFactory.getLog(KHUtil.class);

    public static void main(String[] args) {
        // TODO Auto-generated method stub

    }

    // 将字符串使用sha1加密返回加密字符串(realme)
    public static String getsh1(String inString) {
        if (StringUtils.isEmpty(inString)) {
            return null;
        } else {
            return DigestUtils.shaHex(inString);
        }
    }

    // 将字符串使用base64加密返回加密字符串(realme)
    public static String getbase64(String inString) {

        if (StringUtils.isEmpty(inString)) {
            return null;
        } else {
            try {
                return Base64.getEncoder().encodeToString(inString.getBytes("utf-8"));
            } catch (Exception e) {
                log.warn("将字符串使用base64加密异常:" + e.getMessage());
                return null;
            }
        }
    }

    // 生成指定位数的随机字符串
    public static String getRandomString(int length) {
        String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(62);
            sb.append(str.charAt(number));
        }
        return sb.toString();
    }

    // 生成指随机正整数串
    public static String getIntRandom(int len) {
        //生成六位随机正整数
        Random random = new Random();
        String verificationCode = String.valueOf(random.nextInt(9) + 1);
        for (int i = 0; i < len - 1; i++) {
            verificationCode += random.nextInt(10);
        }
        return verificationCode;
    }

    // 非空校验isNull
    public static boolean isNull(String value) {

        boolean reFlag = true;
        if (value == null || value.length() <= 0) {
            reFlag = true;
        } else {
            reFlag = false;
        }

        return reFlag;
    }

    // 非空校验isNullMSG
    public static String isNullMSG(String key, String value) {

        String reResult = "";
        if (value == null || value.length() <= 0) {
            reResult = key + "必填字段;";
        }
        return reResult;
    }

    // List To String[]
    public static String[] listToStringArr(List<String> inList) {
        String[] strArray = inList.toArray(new String[inList.size()]);
        return strArray;
    }

    // 解析Json值(此方法增加需要解析的key不存在保护)
    public static String GetJV(JSONObject inJson, String getKey) {
        String Rev_Value = null;
        try {
            Rev_Value = inJson.getString(getKey);
        } catch (Exception e) {
            try {
                Rev_Value = String.valueOf(inJson.getLong(getKey));
            } catch (Exception e11) {
                try {
                    Rev_Value = String.valueOf(inJson.getInt(getKey));
                } catch (Exception e1) {
                    try {
                        Rev_Value = String.valueOf(inJson.getJSONArray(getKey));
                    } catch (Exception e2) {
                        try {
                            Rev_Value = String.valueOf(inJson.getJSONObject(getKey));
                        } catch (Exception e3) {
                            Rev_Value = "";
                        }
                    }
                }
            }
        } finally {
            if (Rev_Value == null || Rev_Value.equals("null") || Rev_Value.length() <= 0) {
                Rev_Value = "";
            } else {
                log.debug("GetJV:" + Rev_Value);
            }
        }
        return Rev_Value;
    }

    // 解析获取String[]值
    public static String getStringV(String stringInfo, String key) {

        String reValue = "";
        String[] xArr = stringInfo.split("&");
        int xLen = xArr.length;
        for (int i = 0; i < xLen; i++) {
            String yInfo = xArr[i];
            String[] yArr = yInfo.split("=");
            try {
                if (yArr[0].equals(key)) {
                    try {
                        reValue = yArr[1];
                    } catch (Exception e) {
                        reValue = "";
                        log.debug("异常value:" + yArr.toString());
                    }
                }
            } catch (Exception e) {
                log.warn("异常key=value片段:" + yArr.toString());
            }
        }

        return reValue;

    }

    // MD5加密
    public static String getMD5(String plainText) {
        StringBuffer buf = new StringBuffer("");
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(plainText.getBytes());
            byte b[] = md.digest();
            int i;

            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return buf.toString();
    }

    /*
     * 将时间字符串转换为时间戳
     */
    static String dateToStamp(String s) {
        String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        Date date = null;
        try {
            date = simpleDateFormat.parse(s);
        } catch (Exception e) {
            log.error("dateToStamp Exception:" + e.getMessage());
        }

        long ts = date.getTime();
        res = String.valueOf(ts);
        return res;
    }

    /*
     * 将时间戳转换为时间字符串
     */
    static String stampToDate(String s) {
        String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        long lt = new Long(s);
        Date date = new Date(lt);
        res = simpleDateFormat.format(date);
        return res;
    }


    // 获取文件拓展名
    public static String getExtensionName(String filename) {

        if ((filename != null) && (filename.length() > 0)) {

            int dot = filename.lastIndexOf('.');

            if ((dot > -1) && (dot < (filename.length() - 1))) {

                return filename.substring(dot + 1);

            }

        }

        return filename;

    }

    // 剔除字符串Html标签
    public static String StripHTML(String str) {
        // 如果有双引号将其先转成单引号
        String htmlStr = str.replaceAll("\"", "'");
        String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>"; // 定义script的正则表达式
        String regEx_style = "<style[^>]*?>[\\s\\S]*?<\\/style>"; // 定义style的正则表达式
        String regEx_html = "<[^>]+>"; // 定义HTML标签的正则表达式

        Pattern p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
        Matcher m_script = p_script.matcher(htmlStr);
        htmlStr = m_script.replaceAll(""); // 过滤script标签

        Pattern p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
        Matcher m_style = p_style.matcher(htmlStr);
        htmlStr = m_style.replaceAll(""); // 过滤style标签

        Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
        Matcher m_html = p_html.matcher(htmlStr);
        htmlStr = m_html.replaceAll(""); // 过滤html标签

        return htmlStr.trim(); // 返回文本字符串
    }

    // 比较时间是否在两个时间之间
    public static boolean isTimeRange(String startTime, String nowTime, String endTime) {
        boolean rangeFlag = false;

        log.debug("比较时间信息:startTime=" + startTime + " endTime=" + endTime + " nowTime=" + nowTime);

        DateFormat df = new SimpleDateFormat("HH:mm");
        try {
            Date dt1 = df.parse(startTime);
            Date dt2 = df.parse(nowTime);
            Date dt3 = df.parse(endTime);

            if (dt2.compareTo(dt1) >= 0 && dt3.compareTo(dt2) >= 0) {
                rangeFlag = true;
            } else {
                rangeFlag = false;
            }
        } catch (Exception e) {

            log.warn("比较时间结果Exception:" + e.getMessage());
            rangeFlag = false;
        }

        log.debug("比较时间结果:" + rangeFlag);

        return rangeFlag;
    }


    public static boolean writeFile(String message, String FilePath) {

        long tstartTime, tendTime, startTime, endTime;

        tstartTime = System.currentTimeMillis();
        log.debug("-File写入本地文件参数 Start time:" + tstartTime + "-FilePath:" + FilePath);

        // 将文件内容写入本地服务器
        int i = 0;
        File dirAll = new File(FilePath);
        FileWriter fw = null;
        do {
            startTime = System.currentTimeMillis();

            log.debug("-File[" + i + "]开始将文件内容写入本地服务器:" + "-FilePath:" + FilePath);
            try {
                // 文件夹路径是否存在不存在则创建
                File dir = new File(dirAll.getParent());
                if (!dir.exists()) {
                    log.debug("-File[" + i + "]创建所需路径:" + dirAll.getParent());
                    dir.mkdirs();
                }

                // 检查目标文件是否存在，不存在则创建
                if (!dirAll.exists()) {
                    log.debug("-File[" + i + "]创建写入文件:" + dirAll.getName());
                    dirAll.createNewFile();
                }
                // 向目标文件中写入内容
                fw = new FileWriter(FilePath, false);
                fw.write(message);
                fw.flush();

                fw.close();

                log.debug("-File[" + i + "]写入文件完成...");

            } catch (Exception e) {
                log.error("-File[" + i + "]写入文件失败：", e);
                e.printStackTrace();
            } finally {
                try {
                    if (fw != null) {
                        fw.close();
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                endTime = System.currentTimeMillis();

                log.debug("-File[" + i + "]写入文件结束 Start time:" + startTime + "; End time:" + endTime + "; Run Time:" + (endTime - startTime) + "(ms)");

                i++;

            }
        } while (!dirAll.exists() && i < 3);

        tendTime = System.currentTimeMillis();
        log.debug("-File写入本地文件结束 End time:" + tendTime + "; Run Time:" + (tendTime - tstartTime) + "(ms)");

        return dirAll.exists();

    }

    /**
     * 获取本机IP地址信息，实际可能出现一台服务器多IP
     *
     * @param getType
     * @return
     */
    public static String getHostIP(String getType) {
        String hostInfo = "";
        try {
            InetAddress addr = InetAddress.getLocalHost();
            if (getType.equals("HOSTNAME")) {
                hostInfo = addr.getHostName();
                log.debug("Local HostName: " + hostInfo);

            } else {
                hostInfo = addr.getHostAddress();
                log.debug("Local HostAddress:" + hostInfo);
            }
        } catch (Exception e) {
            log.error("获取本机信息异常:", e);

        }
        return hostInfo;
    }

    // FastJson Null的问题
    public static String FastJsonNull(String value) {

        if (value == null) {
            return "";
        } else {
            return value;
        }
    }

    // 是否内部IP调用
    public static boolean getRemoteHost(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if ((ip == null) || (ip.length() == 0) || ("unknown".equalsIgnoreCase(ip))) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if ((ip == null) || (ip.length() == 0) || ("unknown".equalsIgnoreCase(ip))) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if ((ip == null) || (ip.length() == 0) || ("unknown".equalsIgnoreCase(ip))) {
            ip = request.getRemoteAddr();
        }
        String serverName = request.getServerName();
        log.debug("serverName:" + serverName + " ip:" + ip);

        if (("localhost".equals(serverName)) || ("127.0.0.1".equals(serverName)) || ("127.0.0.1".equals(ip)) || ("0:0:0:0:0:0:0:1".equals(ip))) {
            return true;
        }
        return false;
    }

    // 将Map转为x-www-form-urlencoded
    public static String urlencode(Object params, String key) {
        String res = "";
        if (params instanceof Map) {
            Map<String, Object> _params = (Map<String, Object>) params;
            for (String i : _params.keySet()) {
                String k = key.isEmpty() ? i : (key + "[" + i + "]");
                String encodeValue = urlencode(_params.get(i), k);
                if (!encodeValue.isEmpty()) {
                    res += '&' + encodeValue;
                }
            }
        } else if (params instanceof List) {
            List<Object> _params = (List<Object>) params;
            for (Integer i = 0; i < _params.size(); i++) {
                String k = key.isEmpty() ? i.toString() : (key + "[" + i.toString() + "]");
                String encodeValue = urlencode(_params.get(i), k);
                if (!encodeValue.isEmpty()) {
                    res += '&' + encodeValue;
                }
            }
        } else if (params.getClass().isArray()) {
            Object[] _params;
            if (params instanceof Object[]) {
                _params = (Object[]) params;
            } else if (params instanceof String[]) {
                _params = (String[]) params;
            } else if (params instanceof int[]) {
                _params = ArrayUtils.toObject((int[]) params);
            } else if (params instanceof double[]) {
                _params = ArrayUtils.toObject((double[]) params);
            } else {
                _params = new Object[]{};
            }
            for (Integer i = 0; i < _params.length; i++) {
                String k = key.isEmpty() ? i.toString() : (key + "[" + i.toString() + "]");
                String encodeValue = urlencode(_params[i], k);
                if (!encodeValue.isEmpty()) {
                    res += '&' + encodeValue;
                }
            }
        } else if (params instanceof String) {
            String _params = (String) params;
            try {
                res += '&' + URLEncoder.encode(key, "UTF-8") + '=' + URLEncoder.encode(_params, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        } else if (params instanceof Number) {
            Number _params = (Number) params;
            try {
                res += '&' + URLEncoder.encode(key, "UTF-8") + '=' + URLEncoder.encode(_params.toString(), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        } else {
            return "";
        }
        return res.substring(1);
    }

    // SFJson Null的问题
    public static boolean SFIsNull(String value) {
        boolean reFlag = true;
        if (!KHUtil.isNull(value)) {
            // 尝试转
            try {
                net.sf.json.JSONObject tmpObj = net.sf.json.JSONObject.fromObject(value);

                if (!tmpObj.isNullObject() && !tmpObj.isEmpty()) {
                    reFlag = false;
                } else {
                    // log.warn("SFIsNull 空JSONObject");
                }

            } catch (Exception e) {
                // log.warn("SFIsNull 非JSONObject");
                try {
                    net.sf.json.JSONArray tmpArr = net.sf.json.JSONArray.fromObject(value);

                    if (!tmpArr.isArray() && !tmpArr.isEmpty()) {
                        reFlag = false;
                    } else {
                        // log.warn("SFIsNull 空JSONArray");
                    }

                } catch (Exception e1) {
                    // log.warn("SFIsNull 非JSONArray");
                }
            }

        } else {
            // log.warn("SFIsNull 空值");
        }
        return reFlag;
    }

    /**
     * 是否含有sql注入，返回true表示含有
     *
     * @param obj
     * @return
     */
    public static boolean containsSqlInjection(Object obj) {
        Pattern pattern = Pattern.compile("(.*\\=.*\\-\\-.*)|(.*(\\+|\\-).*)|(.*\\w+(%|\\$|#|&)\\w+.*)|(.*\\|\\|.*)|(.*\\s+(and|or)\\s+.*)|(.*\\b(select|update|union|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute)\\b.*)");
        Matcher matcher = pattern.matcher(obj.toString().toLowerCase());
        return matcher.find();
    }

    public static boolean objIsNull(Object obj) {

        boolean reFlag = true;
        if (obj == null) {
            reFlag = true;
        } else {
            reFlag = false;
        }

        return reFlag;
    }

    public static String getNameWithoutSuffix(String filename) {
        try {
            if ((filename != null) && (filename.length() > 0)) {
                int dot = filename.lastIndexOf(".");
                if ((dot > -1) && (dot < filename.length()))
                    return filename.substring(0, dot);
            }
        } catch (Exception e) {
            log.error(e);
        }
        return filename;
    }

    /*
     * 微信模板消息Data处理
     */
    public static JSONObject wxTemplateData(Map<String, String> dataMap) {

        JSONObject keyJson = new JSONObject();
        for (Map.Entry<String, String> m : dataMap.entrySet()) {
            JSONObject valueJson = new JSONObject();
            valueJson.put("value", m.getValue());
            valueJson.put("color", "#173177");
            keyJson.put(m.getKey(), valueJson);
        }
        return keyJson;
    }

    /*
     * 小程序模板消息Data处理
     */
    public static JSONObject minipTemplateData(Map<String, String> dataMap) {

        JSONObject keyJson = new JSONObject();
        for (Map.Entry<String, String> m : dataMap.entrySet()) {
            JSONObject valueJson = new JSONObject();
            valueJson.put("value", m.getValue());
            keyJson.put(m.getKey(), valueJson);
        }
        return keyJson;
    }

    public static String ASCIIORDER(Map<String, String> map) throws UnsupportedEncodingException {
        net.sf.json.JSONObject result = new net.sf.json.JSONObject();
        // 对所有传入参数按照字段名的 ASCII 码从小到大排序
        List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(map.entrySet());
        Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {
            public int compare(Map.Entry<String, String> A, Map.Entry<String, String> B) {
                return (A.getKey()).toString().compareTo(B.getKey());
            }
        });

        // 构造签名键值的格式
        StringBuilder stringsign = new StringBuilder();
        StringBuilder sign = new StringBuilder();
        for (Map.Entry<String, String> item : infoIds) {
            if (item.getKey() != null || item.getKey() != "") {
                String key = item.getKey();
                String val = item.getValue();
                if (!(val == "" || val == null)) {
                    sign.append(key + "=" + URLEncoder.encode(val, "UTF-8") + "&");
                }
                if (!(val == "" || val == null) && !(key == "key")) {
                    stringsign.append(key + "=" + val + "&");
                }
            }
        }
        String md5sign = Util.getMD5Str(sign.substring(0, sign.length() - 1));
        return stringsign.append("sign=" + md5sign).toString();
    }


    // 解析Mapn值(此方法增加需要解析的key不存在保护)
    public static String GetMapV(Map inMap, String getKey) {
        String Rev_Value = null;
        try {
            Rev_Value = String.valueOf(inMap.get(getKey));
        } catch (Exception e) {

            Rev_Value = "";
        } finally {
            if (Rev_Value == null || Rev_Value.equals("null") || Rev_Value.length() <= 0) {
                Rev_Value = "";
            }
        }
        return Rev_Value;
    }


    // 工具方法
    public static String getQueryString(Map<String, String> params) {
        String url = "";
        if (params == null) {
            return url;
        }

        StringBuilder builder = new StringBuilder(url);

        int i = 0;
        for (String key : params.keySet()) {
            String value = params.get(key);
            if (value == null) { // 过滤空的key
                continue;
            }

            if (i != 0) {
                builder.append('&');
            }

            builder.append(key);
            builder.append('=');
            builder.append(encode(value));

            i++;
        }

        return builder.toString();
    }

    // 工具方法
    public static String encode(String input) {
        if (input == null) {
            return "";
        }

        try {
            return URLEncoder.encode(input, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return input;
    }


    // 解析Json值(此方法增加需要解析的key不存在保护)
    public static String GetSFJV(net.sf.json.JSONObject inJson, String getKey) {
        String Rev_Value = null;
        try {
            Rev_Value = inJson.getString(getKey);
        } catch (Exception e) {
            try {
                Rev_Value = String.valueOf(inJson.getLong(getKey));
            } catch (Exception e11) {
                try {
                    Rev_Value = String.valueOf(inJson.getInt(getKey));
                } catch (Exception e1) {
                    try {
                        Rev_Value = String.valueOf(inJson.getJSONArray(getKey));
                    } catch (Exception e2) {
                        try {
                            Rev_Value = String.valueOf(inJson.getJSONObject(getKey));
                        } catch (Exception e3) {
                            Rev_Value = "";
                        }
                    }
                }
            }
        } finally {
            if (Rev_Value == null || Rev_Value.equals("null") || Rev_Value.length() <= 0) {
                Rev_Value = "";
            }
        }
        return Rev_Value;
    }

    public static String GetSFJV(net.sf.json.JSONObject inJson, String getKey, String defaultValue) {
        String res_Str = GetSFJV(inJson, getKey);

        res_Str = KHUtil.isNull(res_Str) ? defaultValue : res_Str;

        return res_Str;
    }

    // 解析Json值(此方法增加需要解析的key不存在保护)
    public static String GetFSJV(com.alibaba.fastjson.JSONObject inJson, String getKey) {
        String Rev_Value = null;
        try {
            Rev_Value = inJson.getString(getKey);
        } catch (Exception e) {
            try {
                Rev_Value = String.valueOf(inJson.getLong(getKey));
            } catch (Exception e1) {
                try {
                    Rev_Value = String.valueOf(inJson.getInteger(getKey));
                } catch (Exception e2) {
                    try {
                        Rev_Value = String.valueOf(inJson.getJSONArray(getKey));
                    } catch (Exception e3) {
                        try {
                            Rev_Value = String.valueOf(inJson.getJSONObject(getKey));
                        } catch (Exception e4) {
                            Rev_Value = "";
                        }
                    }
                }
            }
        } finally {
            if (Rev_Value == null || Rev_Value.equals("null") || Rev_Value.length() <= 0) {
                Rev_Value = "";
            }
        }
        return Rev_Value;
    }

    public static String GetFSJV(com.alibaba.fastjson.JSONObject inJson, String getKey, String defaultValue) {
        String res_Str = GetFSJV(inJson, getKey);

        res_Str = KHUtil.isNull(res_Str) ? defaultValue : res_Str;

        return res_Str;
    }

    // Map字符串转List对象(近保留Map Key)
    private static List<String> mapStringToList(String str) {
        str = str.substring(1, str.length() - 1);
        String[] strs = str.split(",");
        List<String> toList = new ArrayList<>();
        for (String string : strs) {
            String key = string.split("=")[0];
            toList.add(key.trim());
        }
        return toList;
    }

    // Map字符串转Map对象
    private static Map<String, Object> mapStringToMap(String str) {
        str = str.substring(1, str.length() - 1);
        String[] strs = str.split(",");
        Map<String, Object> map = new HashMap<String, Object>();
        for (String string : strs) {
            String key = string.split("=")[0];
            String value = string.substring(string.indexOf("=") + 1);
            map.put(key.trim(), value.trim());
        }
        return map;
    }

}
